package per.hnvcam.searchext.text.impl;

import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import per.hnvcam.searchext.text.GoogleSearchHandler;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by IntelliJ IDEA.
 * User: Vi Cam
 * Date: 16/01/2012
 * Time: 21:25
 * To change this template use File | Settings | File Templates.
 */
public class GoogleSearchHandlerImpl implements GoogleSearchHandler {
   private static final String MATCHING_TAG = "a";
   private static final String MATCHING_ATTRIBUTE_NAME = "class";
   private static final String MATCHING_ATTRIBUTE_VALUE = "1";
   private static final String MATCHING_LINK_ATTRIBUTE = "href";

   private boolean gettingContent;
   private String currentLink;
   private StringBuilder currentContent;
   private Map<String, String> searchResults;
   private String [] searchTexts;

   public GoogleSearchHandlerImpl() {
      currentContent = new StringBuilder();
      searchResults = new HashMap<String, String>();
   }

   @Override
   public void setDocumentLocator(Locator locator) {
      //To change body of implemented methods use File | Settings | File Templates.
   }

   @Override
   public void startDocument() throws SAXException {
      //To change body of implemented methods use File | Settings | File Templates.
   }

   @Override
   public void endDocument() throws SAXException {
      //To change body of implemented methods use File | Settings | File Templates.
   }

   @Override
   public void startPrefixMapping(String prefix, String uri) throws SAXException {
      //To change body of implemented methods use File | Settings | File Templates.
   }

   @Override
   public void endPrefixMapping(String prefix) throws SAXException {
      //To change body of implemented methods use File | Settings | File Templates.
   }

   @Override
   public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
      if (qName.toLowerCase().equals(MATCHING_TAG)) {
         String linkValue = null;
         for (int i = 0; i < atts.getLength(); i++) {
            String attName = atts.getQName(i).toLowerCase();
            if (attName.equals(MATCHING_LINK_ATTRIBUTE)) {
               linkValue = atts.getValue(i);
            }
         }
         currentContent.setLength(0);
         currentLink = linkValue;
         gettingContent = true;
      }
   }

   @Override
   public void endElement(String uri, String localName, String qName) throws SAXException {
      if (gettingContent && qName.toLowerCase().equals(MATCHING_TAG)) {
         String content = currentContent.toString();
         if (isContainSearchText(content.toLowerCase()) && currentLink.contains("http://")) {
            searchResults.put(refactorLink(currentLink), content);
         }
         gettingContent = false;
      }
   }

   private String refactorLink(String currentLink) {
      int startLink = currentLink.lastIndexOf("http://");
      int endLink = currentLink.indexOf("&", startLink);
      if (endLink <= 0) {
         endLink = currentLink.length();
      }
      return currentLink.substring(startLink, endLink);
   }

   private boolean isContainSearchText(String s) {
      for (String text : searchTexts) {
         if (s.contains(text)) {
            return true;
         }
      }
      return false;
   }

   @Override
   public void characters(char[] ch, int start, int length) throws SAXException {
      if (gettingContent) {
         currentContent.append(ch, start, length);
      }
   }

   @Override
   public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
      //To change body of implemented methods use File | Settings | File Templates.
   }

   @Override
   public void processingInstruction(String target, String data) throws SAXException {
      //To change body of implemented methods use File | Settings | File Templates.
   }

   @Override
   public void skippedEntity(String name) throws SAXException {
      //To change body of implemented methods use File | Settings | File Templates.
   }

   @Override
   public Map<String, String> getSearchResults() {
      return searchResults;
   }

   @Override
   public void setSearchString(String searchString) {
      this.searchTexts = searchString.toLowerCase().split(" ");
   }
}
